package cn.topevery.garden.wapi.controller;

import cn.topevery.garden.dal.logic.CoreIndicatorsRuleLogic;
import cn.topevery.garden.dal.logic.CriterionDefLogic;
import cn.topevery.garden.dal.logic.CriterionEvaluationLogic;
import cn.topevery.garden.dal.logic.CriterionEvaluationShowLogic;
import cn.topevery.garden.entity.dto.CriterionDefDTO;
import cn.topevery.garden.entity.po.CoreIndicatorsItem;
import cn.topevery.garden.entity.po.CriterionDef;
import cn.topevery.garden.entity.po.CriterionEvaluationShow;
import cn.topevery.garden.entity.query.CriterionDefQuery;
import cn.topevery.garden.entity.vo.CriterionDefVO;
import cn.topevery.garden.entity.vo.CriterionTableVO;
import cn.topevery.garden.entity.vo.CriterionTreeVO;
import cn.topevery.garden.wapi.model.CriterionEvaluationParam;
import cn.topevery.garden.wapi.model.CriterionParam;
import cn.topevery.garden.wapi.model.CriterionTableParam;
import com.github.dozermapper.core.Mapper;
import hw.topevery.framework.db.entity.DataPager;
import hw.topevery.framework.util.ExcelUtil;
import hw.topevery.framework.web.JsonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 综合评价标准定义表
 *
 * @author code-generate
 * @date 2022-01-05
 */
@Api(tags = "综合评价标准定义表")
@RestController
@RequestMapping("/criterion")
public class CriterionController extends BaseController {

    @Autowired
    private Mapper mapper;

    @Autowired
    CriterionDefLogic criterionDefLogic;

    @Autowired
    private CoreIndicatorsRuleLogic coreIndicatorsService;

    @Autowired
    private CriterionEvaluationLogic criterionEvaluationService;

    @Autowired
    private CriterionEvaluationShowLogic criterionEvaluationShowService;


    /**
     * 获取综合评价标准定义表分页列表
     *
     * @param query
     * @return
     */
    @ApiOperation(value = "获取综合评价标准定义表页列表")
    @PostMapping("/listPage")
    public JsonResult<DataPager<CriterionDefVO>> listPage(@RequestBody CriterionDefQuery query) {
        return JsonResult.ok(criterionDefLogic.listPage(query));
    }

    @ApiOperation("新增/编辑 综合评价标准定义表信息")
    @PostMapping("/saveOrUpdate")
    public JsonResult<Boolean> saveOrUpdate(@Valid @RequestBody CriterionDefDTO dto) {
        criterionDefLogic.saveOrUpdate(getUser().id.toString(),mapper.map(dto, CriterionDef.class));
        return JsonResult.ok(true);
    }

    @ApiOperation("通过Id获取详情")
    @GetMapping("/getInfoById")
    public JsonResult<CriterionDefVO> getInfoById(@RequestParam Integer id) {
        CriterionDef entity = criterionDefLogic.getEntity(id);
        CriterionDefVO vo= mapper.map(entity, CriterionDefVO.class);
        return JsonResult.ok(vo);
    }

    @ApiOperation("根据自增ID批量删除")
    @PostMapping("/deleteBatchById")
    public JsonResult<Boolean> deleteBatchById(@RequestBody Integer[] ids) {
        criterionDefLogic.deleteBatchById(getUser().id.toString(),ids);
        return JsonResult.ok(true);
    }

    @ApiOperation("导出综合评价标准定义表信息")
    @GetMapping("/export")
    public void export(CriterionDefQuery query, HttpServletResponse response) {
        List<CriterionDefVO> list = criterionDefLogic.listPage(query).records;
        ExcelUtil.exportExcel(list, "综合评价标准定义表", "sheet1", CriterionDefVO.class, "综合评价标准定义表", response);
    }

    @ApiOperation(value = "新增标准")
    @PostMapping(value = "/insert")
    public JsonResult<?> insert(@RequestBody CriterionParam param) {
        criterionDefLogic.insert(param.getCriterionList(), getUser().id);
        return JsonResult.ok("新增成功！");
    }

    @GetMapping(value = "/getById")
    @ApiOperation(value = "通过标准uuid获取信息")
    public JsonResult<?> getCriterionById(String criterionId) {
        if (StringUtils.isBlank(criterionId)) {
            return JsonResult.error("标准id不规范");
        }
        List<CriterionDef> criterionList = criterionDefLogic.getById(criterionId);
        return JsonResult.ok(criterionList);
    }

    @PostMapping(value = "/update")
    @ApiOperation(value = "修改")
    public JsonResult<?> update(@RequestBody CriterionParam param) {
        criterionDefLogic.update(param.getCriterionList(), getUser().id);
        return JsonResult.ok("修改成功");
    }

    @GetMapping(value = "/deleteById")
    @ApiOperation(value = "通过标准uuid删除")
    public JsonResult<?> deleteByCriterionId(String criterionId) {
        if (StringUtils.isBlank(criterionId)) {
            return JsonResult.error("标准id不规范");
        }
        List<CriterionDef> list = criterionDefLogic.getListByPid(criterionId);
        if (list != null && !list.isEmpty()) {
            return JsonResult.error("该节点有子节点，无法删除！");
        }
        criterionDefLogic.delete(criterionId, getUser().id);
        return JsonResult.ok("删除成功");
    }

    @PostMapping(value = "/getTableInfo")
    @ApiOperation(value = "获取综合标准表格")
    public JsonResult<List<CriterionTableVO>> getTableInfo(@RequestBody CriterionTableParam param) {
        Map<String, String> map = new HashMap<>();
        map.put("criterionId", param.getCriterionId());
        map.put("mapId", param.getMapId());
        map.put("year", param.getYear());
        List<CriterionTableVO> list = criterionDefLogic.getCriterionTableByMapIdAndYear(map, param.getIsReach(), param.getIsShow());
        return JsonResult.ok(list);
    }

    @GetMapping(value = "/getListByPid")
    @ApiOperation(value = "通过父级uuid获取列表")
    public JsonResult<List<CriterionDef>> getListByPid(String pid) {
        List<CriterionDef> list = criterionDefLogic.getListByPid(pid);
        list = list.stream().peek(temp -> {
            CriterionDef criterion = criterionDefLogic.getRelationById(temp.getCriterionId());
            if (criterion != null) {
                List<CriterionDef> criterionList = criterionDefLogic.getById(temp.getCriterionId());
                String delimiter;
                if (criterionList.get(1).getRelationType() == 1) {
                    delimiter = "和";
                } else {
                    delimiter = "或";
                }
                for (CriterionDef criterionDef : criterionList) {
                    if (StringUtils.isNotBlank(criterionDef.getExpression())) {
                        List<CoreIndicatorsItem> expressionInfo = coreIndicatorsService.info(criterionDef.getExpression());
                        if (expressionInfo != null && !expressionInfo.isEmpty()) {
                            criterionDef.setExpressionStr(expressionInfo.get(0).getName() + "/" + expressionInfo.get(1).getName());
                        }
                    }
                }
                temp.setCriterionName(criterionList.stream().map(CriterionDef::getCriterionName)
                        .collect(Collectors.joining(delimiter)));
                temp.setExpressionStr(criterionList.stream().map(CriterionDef::getExpressionStr)
                        .collect(Collectors.joining("、")));
            } else {
                if (StringUtils.isNotBlank(temp.getExpression())) {
                    List<CoreIndicatorsItem> expressionInfo = coreIndicatorsService.info(temp.getExpression());
                    temp.setExpressionStr(expressionInfo.get(0).getName() + "/" + expressionInfo.get(1).getName());
                }
            }
        }).collect(Collectors.toList());
        return JsonResult.ok(list);
    }

    @GetMapping(value = "/getOneById")
    @ApiOperation(value = "通过uuid获取单个规则")
    public JsonResult<CriterionDef> getOneById(String criterionId) {
        CriterionDef criterion = criterionDefLogic.getOneById(criterionId);
        return JsonResult.ok(criterion);
    }

    @GetMapping(value = "/getEvaluation")
    @ApiOperation(value = "获取评价信息")
    public JsonResult<?> getByCriterionIdAndMapId(String criterionId, String mapId) {
        if (StringUtils.isBlank(criterionId) || StringUtils.isBlank(mapId)) {
            return JsonResult.error("参数不合法");
        }
//        CriterionEvaluation evaluation = criterionEvaluationService.getByCriterionIdAndMapId(criterionId, mapId);
        List<CriterionDef> criterionDefList = criterionDefLogic.getById(criterionId);
        List<CriterionEvaluationShow> evaluationList = criterionEvaluationShowService.getRelationListByCriterionIdAndMapId(criterionDefList, mapId);
        return JsonResult.ok(evaluationList);
    }

    @PostMapping(value = "/evaluation")
    @ApiOperation(value = "评价")
    public JsonResult<?> evaluation(@RequestBody CriterionEvaluationParam param) {
        criterionEvaluationService.evaluation(param.getEvaluationList(), getUser().id);
        criterionEvaluationShowService.evaluation(param.getEvaluationShowList(), getUser().id);
        return JsonResult.ok("评价成功");
    }

    @GetMapping(value = "/getCountList")
    @ApiOperation(value = "获取数量列表")
    public JsonResult<?> getCountList(String year, Integer type) {
        List<Map<String, Object>> list = criterionDefLogic.getCountList(year, type);
        return JsonResult.ok(list);
    }

    @GetMapping(value = "/getHomeInfo")
    @ApiOperation(value = "获取首页指标项信息")
    public JsonResult<?> getHomeInfo(String mapId) {
        List<Map<String, Object>> list = criterionDefLogic.getHomeInfo(mapId);
        return JsonResult.ok(list);
    }

    @GetMapping(value = "/getHomeInfoShow")
    @ApiOperation(value = "获取首页指标项信息")
    public JsonResult<?> getHomeInfoShow(String mapId) {
        List<Map<String, Object>> list = criterionDefLogic.getHomeInfoShow(mapId);
        return JsonResult.ok(list);
    }


    @ApiOperation(value = "通过标准根节点id获取标准树")
    @GetMapping(value = "/getTree")
    public JsonResult<List<CriterionTreeVO>> getTree(String rootId, boolean isNeedLeaf, Integer layer) {
        List<CriterionDef> rootList = criterionDefLogic.getRootListByCriterionId(rootId);
        List<CriterionTreeVO> tree = buildTree(rootList, isNeedLeaf, layer);
        return JsonResult.ok(tree);
    }

    private List<CriterionTreeVO> buildTree(List<CriterionDef> rootList, boolean isNeedLeaf, Integer layer) {
        List<CriterionTreeVO> tree = new ArrayList<>();
        CriterionTreeVO node;
        for (CriterionDef criterion : rootList) {
            if ((!isNeedLeaf && criterion.getLayer() == 3) || criterion.getLayer().equals(layer)) {
                continue;
            }
            node = new CriterionTreeVO();
            node.setId(criterion.getCriterionId());
            node.setCriterionName(criterion.getCriterionName());
            node.setLayer(criterion.getLayer());
            node.setIsLeaf(criterion.getIsLeaf());
            node.setIsCoreIndicator(criterion.getIsCoreIndicator());
            node.setExpression(criterion.getExpression());
            node.setOrderNum(criterion.getOrderNum());
            if (criterion.getIsLeaf() != 0) {
                node.setChildren(buildTree(criterionDefLogic.getListByPid(criterion.getCriterionId()), isNeedLeaf, layer));
            }
            tree.add(node);
        }
        return tree;
    }
}
